﻿/*
    This file is part of nDoctor Light

    NDoctor is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    NDoctor is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with NDoctor.  If not, see <http://www.gnu.org/licenses/>.
*/
namespace Probel.Ldoc.Stat
{
    using System;
    using System.Collections.Generic;
    using System.Linq;

    using log4net;

    using NHibernate;
    using NHibernate.Linq;

    using Probel.Ldoc.Stat.Entities;
    using Probel.Ldoc.Stat.Helpers;
    using Probel.Ldoc.Stat.Orm;

    public class StatManager
    {
        #region Fields

        private readonly ISessionFactory Factory;
        private readonly ILog Logger = LogManager.GetLogger(LogHelper.Name);

        #endregion Fields

        #region Constructors

        public StatManager(string server, string database, string userName, string password)
        {
            this.Logger.DebugFormat("SID: {0}", new StatHelper().GetSid());
            //this.Factory = new MySqlSessionFactoryBuilder(server, userName, password, database).BuildFactory(true, true);
            this.Factory = new MySqlSessionFactoryBuilder(server, userName, password, database).BuildFactory();
        }

        #endregion Constructors

        #region Methods

        public StatLogger Register(string version, string note = "")
        {
            var sessionStart = DateTime.Now.ToUniversalTime();
            var sid = new StatHelper().GetSid();

            using (var session = Factory.OpenSession())
            {
                var app = new Application() { ApplicationId = sid, Note = note, Sessions = new List<Session>(), Registration = sessionStart };

                if (!this.Exists(sid, session))
                {
                    app.Id = (Guid)session.Save(app);
                    session.Flush();
                    this.Logger.Debug("New application created");

                    return new StatLogger(app, version, Factory, sessionStart);
                }
                else
                {
                    this.Logger.Debug("SID exists!");
                    return new StatLogger(this.GetApplicationFrom(sid, session), version, Factory, sessionStart);
                }
            }
        }

        private bool Exists(string sid, ISession session)
        {
            return (from a in session.Query<Application>()
                    where a.ApplicationId == sid
                    select a).Count() > 0;
        }

        private Application GetApplicationFrom(string sid, ISession session)
        {
            return (from a in session.Query<Application>()
                    where a.ApplicationId == sid
                    select a).Single();
        }

        #endregion Methods
    }
}